#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "wrap.h"
int main(int argc, char const *argv[])
{
        if(argc < 2){
                printf("eg: ./a.out port\n");
                exit(1);       
        }
        int port = atoi(argv[1]);

        int lfd = Socket(AF_INET, SOCK_STREAM,0);

        struct sockaddr_in serv_addr;
        socklen_t serv_len = sizeof(serv_addr);
        memset(&serv_addr,0,serv_len);
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        serv_addr.sin_port = htons(port);
        Bind(lfd,(struct sockaddr *)&serv_addr, serv_len);

        Listen(lfd,36);
        printf("Start accept ......\n");

        struct sockaddr_in client_addr;
        socklen_t client_len = sizeof(client_addr);

        int maxfd = lfd;
        fd_set reads, temp;
        FD_ZERO(&reads);
        FD_SET(lfd,&reads);
        while (1){
                //委托内核做IO检测
                temp = reads;
                int ret = select(maxfd+1, &temp, NULL,NULL,NULL);
                if(ret == -1){
                        perr_exit("select error");
                }
                //客户端发起了新连接
                if(FD_ISSET(lfd, &temp)){
                        //接收连接请求 - accept不阻塞
                        int cfd = Accept(lfd,(struct sockaddr*)&client_addr, &client_len);      
                        if(cfd == -1){
                                perr_exit("accept error");
                        }
                        printAddr("new client connect", &client_addr);
                        //将cfd加入到待检测的读集合中 - 下一次就可以检测到了
                        FD_SET(cfd, &reads);
                        //更新最大的文件描述符
                        maxfd = maxfd < cfd ? cfd : maxfd;
                }
                // 已经连接的客户端有数据到达
                for ( int i = lfd+1; i <= maxfd; ++i){
                        if(FD_ISSET(i,&temp)){
                                char buf[1024] = {0};
                                int len = recv(i,buf,sizeof(buf),0);
                                if(len == -1){
                                        perr_exit("recv error");
                                }
                                else if(len == 0){
                                        printf("客户端已经断开\n");
                                        Close(i);
                                        //从读集合中删除
                                        FD_CLR(i, &reads);
                                }
                                else{
                                        printf("recv buf: %s\n", buf);
                                        send(i,buf,strlen(buf)+1, 0);
                                }
                        }
                }                
        }
        Close(lfd);
        return 0;
}
